/*
                        *********************
*************************** C SOURCE FILE ************************************
**                      *********************                               **
**                                                                          **
*/

#define _SERVER_C_SRC

/****************************************************************************/
/**                                                                        **/
/** MODULES USED                                                           **/
/**                                                                        **/
/****************************************************************************/

#include "server.h"

/****************************************************************************/
/**                                                                        **/
/** DEFINITIONS AND MACROS                                                 **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** TYPEDEFS AND STRUCTURES                                                **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** PROTOTYPES OF LOCAL FUNCTIONS                                          **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** EXPORTED VARIABLES                                                     **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** GLOBAL VARIABLES                                                       **/
/**                                                                        **/
/****************************************************************************/



/****************************************************************************/
/**                                                                        **/
/** EXPORTED FUNCTIONS                                                     **/
/**                                                                        **/
/****************************************************************************/



/****************************************************************************/
/**                                                                        **/
/** LOCAL FUNCTIONS                                                        **/
/**                                                                        **/
/****************************************************************************/
int main()
{
	int16s 	server_sockfd, client_sockfd;
	int16s 	server_len, client_len;
	struct sockaddr_in server_address;
	struct sockaddr_in client_address;
	int16s 	result;
	int16s	i,j,n[4];
	int16u	state,N;
	int16u	answer,Q[4];
	int16u	lx[4],ly[4];
	int16u	tempx[4][3];
	int16u	tempy[4][3];
	int16u 	round = 0;
	int16s 	buf[4][2];

	/* Create an unnamed socket for the server. */
	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

	/* Assign a name to a socket. */
	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = inet_addr("192.168.1.245");
	server_address.sin_port = 1803;
	server_len = sizeof(server_address);
	result = bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
	if(result == -1)
	{
		perror("OOPS!!: bind function error\n");
		exit(1);
	}
		
	/* Create a connection queue and wait for clients. */
	result = listen(server_sockfd, 5);
	if(result == -1)
	{
		perror("OOPS!!: listen function error\n");
		exit(1);
	}

	while(1)
	{
		printf("server waiting round: %02d\n", round);
		round++;

		/* Accept a connection. */
		client_len = sizeof(client_address);
		client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);

	for(i=0;i<=4;i++)
	{
		n[i] = 0;
		Q[i] = 0;
		lx[i] = 0;
		ly[i] = 0;
		for(j=0;j<=3;j++)
		{
			tempx[i][j] = 0;
			tempy[i][j] = 0;
		}
	}

	state = data;
	N = 0;
	while(state <= sendback)
	{
		switch(state)
		{
			case data:
				switch(N)
				{
					case 0:
						result=read(client_sockfd, buf[0], 2*sizeof(int16s));
						if(result==-1)
						{
							answer=0;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						else
						{
							answer=1;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						N=1;
					break;
					case 1:
						result=read(client_sockfd, buf[1], 2*sizeof(int16s));
						if(result==-1)
						{
							answer=0;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						else
						{
							answer=1;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						N=2;
					break;
					case 2:
						result=read(client_sockfd, buf[2], 2*sizeof(int16s));
						if(result==-1)
						{
							answer=0;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						else
						{
							answer=1;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						N=3;
					break;

					case 3:
						result=read(client_sockfd, buf[3], 2*sizeof(int16s));
						if(result==-1)
						{
							answer=0;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						else
						{
							answer=1;
							write(client_sockfd,&answer, sizeof(int16u));
						}
						N=4;
						state = cal;
					break;
				}
			break;
			case cal:
	for(i=0;i<4;i++)
	{
		if((buf[i][0]>0)&&(buf[i][1]>0))
		{
			if(!((buf[i][0]==tempx[0][0])||(buf[i][0]==tempx[0][1])||(buf[i][0]==tempx[0][2])))
			{
				lx[0] = buf[i][0]-lx[0];
			}
			tempx[0][n[0]] = buf[i][0];
			if(!((buf[i][1]==tempy[0][0])||(buf[i][1]==tempy[0][1])||(buf[i][1]==tempy[0][2])))
			{
				ly[0] = buf[i][1]-ly[0];
			}
			tempy[0][n[0]] = buf[i][1];
			n[0]++;
		}
		else if((buf[i][0]>0)&&(buf[i][1]<0))
		{
			if(!((buf[i][0]==tempx[1][0])||(buf[i][0]==tempx[1][1])||(buf[i][0]==tempx[1][2])))
			{
				lx[1] = buf[i][0]-lx[1];
			}
			tempx[1][n[1]] = buf[i][0];
			if(!((buf[i][1]==tempy[1][0])||(buf[i][1]==tempy[1][1])||(buf[i][1]==tempy[1][2])))
			{
				ly[1] = buf[i][1]-ly[1];
			}
			tempy[1][n[1]] = buf[i][1];
			n[1]++;
		}
		else if((buf[i][0]<0)&&(buf[i][1]<0))
		{
			if(!((buf[i][0]==tempx[2][0])||(buf[i][0]==tempx[2][1])||(buf[i][0]==tempx[2][2])))
			{
				lx[2] = buf[i][0]-lx[2];
			}
			tempx[2][n[2]] = buf[i][0];
			if(!((buf[i][1]==tempy[2][0])||(buf[i][1]==tempy[2][1])||(buf[i][1]==tempy[2][2])))
			{
				ly[2] = buf[i][1]-ly[2];
			}
			tempy[2][n[2]] = buf[i][1];
			n[2]++;
		}
		else if((buf[i][0]<0)&&(buf[i][1]>0))
		{
			if(!((buf[i][0]==tempx[3][0])||(buf[i][0]==tempx[3][1])||(buf[i][0]==tempx[3][2])))
			{
				lx[3] = buf[i][0]-lx[3];
			}
			tempx[3][n[3]] = buf[i][0];
			if(!((buf[i][1]==tempy[3][0])||(buf[i][1]==tempy[3][1])||(buf[i][1]==tempy[3][2])))
			{
				ly[3] = buf[i][1]-ly[3];
			}
			tempy[3][n[3]] = buf[i][1];
			n[3]++;
		}
	}
				Q[0] = abs(lx[0]*ly[0]);
				Q[1] = abs(lx[1]*ly[1]);
				Q[2] = abs(lx[2]*ly[2]);
				Q[3] = abs(lx[3]*ly[3]);

				printf("\n");
				printf("Quadrant 1 = %d\n",Q[0]);
				printf("Quadrant 2 = %d\n",Q[1]);
				printf("Quadrant 3 = %d\n",Q[2]);
				printf("Quadrant 4 = %d\n",Q[3]);

				state = sendback;
			break;
			case sendback:
				
				write(client_sockfd,Q, 4*sizeof(int16s));
				read(client_sockfd,&answer, sizeof(int16u));
				if(answer)
				{
					printf("Sendback complete\n");
				}
				else
				{
					printf("Client not reply\n");
				}
				state = sendback+1;
			break;
		}
	}
		/* Close socket. */
		close(client_sockfd);
	}

}

/****************************************************************************/
/**                                                                        **/
/** EOF                                                                    **/
/**                                                                        **/
/****************************************************************************/
 
